using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using CodePlex.Resourceful;

namespace CodePlex.Resourceful.Amazon.S3
{

    /*
HTTP/1.1 200 OK
x-amz-id-2: gyB+3jRPnrkN98ZajxHXr3u7EFM67bNgSAxexeEHndCX/7GRnfTXxReKUQF28IfP
x-amz-request-id: 3B3C7C725673C630
Date: Thu, 17 Nov 2005 07:13:49 GMT
Content-Type: application/xml
Content-Length: 302
Connection: close
Server: AmazonS3

<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Name>quotes</Name>
  <Prefix>N</Prefix>
  <Marker>Ned</Marker>
  <MaxKeys>40</MaxKeys>
  <IsTruncated>false;</IsTruncated>
  <Delimiter>/</Delimiter>
  <Contents>
    <Key>Nelson</Key>
    <LastModified>2005-11-17T07:13:48Z</LastModified>
    <ETag>&quot;828ef3fdfa96f00ad9f27c383fc9ac7f&quot;</ETag>
    <Size>5</Size>
    <StorageClass>STANDARD</StorageClass>
    <Owner>
      <ID>bcaf1ffd86f41caff1a493dc2ad8c2c281e37522a640e161ca5fb16fd081034f</ID>
      <DisplayName>webfile</DisplayName>
     </Owner>
  </Contents>
  <Contents>
    <Key>Neo</Key>
    <LastModified>2005-11-17T07:13:48Z</LastModified>
    <ETag>&quot;828ef3fdfa96f00ad9f27c383fc9ac7f&quot;</ETag>
    <Size>4</Size>
    <StorageClass>STANDARD</StorageClass>
     <Owner>
      <ID>bcaf1ffd86f41caff1a493dc2ad8c2c281e37522a640e161ca5fb16fd081034f</ID>
      <DisplayName>webfile</DisplayName>
    </Owner>
 </Contents>
   <CommonPrefixes>
    <Prefix>photos/2006/January/</Prefix>
  </CommonPrefixes>
 
     
</ListBucketResult>
     */



    internal class InternalListBucketResult
    {
        private readonly string _name;
        private readonly string _prefix;
        private readonly string _marker;
        private readonly int _maxKeys;
        private readonly bool _isTruncated;
        private readonly string _delimiter;

        private readonly ReadOnlyList<Key> _objects;
        private readonly ReadOnlyList<string> _commonPrefixes;


        public InternalListBucketResult(string name, string prefix, string marker, int maxKeys, bool isTruncated, string delimiter,
            IEnumerable<Key> objects, IEnumerable<string> commonPrefixes)
        {
            _name = name;
            _prefix = prefix;
            _marker = marker;
            _maxKeys = maxKeys;
            _isTruncated = isTruncated;
            _delimiter = delimiter;

            _objects = new ReadOnlyList<Key>(objects);
            _commonPrefixes = new ReadOnlyList<string>(commonPrefixes);
        }

        public string Name
        {
            get
            {
                return _name;
            }
        }
        public string Prefix
        {
            get
            {
                return _prefix;
            }
        }
        public string Marker
        {
            get
            {
                return _marker;
            }
        }

        public int MaxKeys
        {
            get
            {
                return _maxKeys;
            }
        }

        public bool IsTruncated
        {
            get
            {
                return _isTruncated;
            }
        }
        public string Delimiter
        {
            get
            {
                return _delimiter;
            }
        }

        public ReadOnlyList<Key> Objects
        {
            get
            {
                return _objects;
            }
        }

        public ReadOnlyList<string> CommonPrefixes
        {
            get
            {
                return _commonPrefixes;
            }
        }

        public static InternalListBucketResult Parse(XmlReader reader)
        {

            string name = null;
            string prefix = null;
            string marker = null;
            int maxKeys = int.MinValue;
            bool isTruncated = false;
            string delimiter = null;

            List<Key> objects = new List<Key>();
            List<string> commonPrefixes = new List<string>();

            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    if (reader.Name == "Name")
                    {
                        name = Utils.ReadString(reader);
                    }
                    else if (reader.Name == "Prefix")
                    {
                        prefix = Utils.ReadString(reader);
                    }
                    else if (reader.Name == "Marker")
                    {
                        marker = Utils.ReadString(reader);
                    }
                    else if (reader.Name == "MaxKeys")
                    {
                        maxKeys = int.Parse(Utils.ReadString(reader));
                    }
                    else if (reader.Name == "IsTruncated")
                    {
                        isTruncated = bool.Parse(Utils.ReadString(reader));
                    }
                    else if (reader.Name == "Delimiter")
                    {
                        delimiter = Utils.ReadString(reader);
                    }
                    else if (reader.Name == "Contents")
                    {
                        objects.Add(Key.Parse(reader));
                    }
                    else if (reader.Name == "CommonPrefixes")
                    {
                        commonPrefixes.AddRange(ParseCommonPrefixes(reader));
                    }
                }

                if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "ListBucketResult")
                {
                    return new InternalListBucketResult(name, prefix, marker, maxKeys, isTruncated,delimiter, objects,commonPrefixes);
                }

            }

            throw CodePlexException.Format("Failed to parse list-bucket-result.");
        }

        private static IEnumerable<string> ParseCommonPrefixes(XmlReader reader)
        {
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    if (reader.Name == "Prefix")
                    {
                        yield return Utils.ReadString(reader);
                    }
                }

                if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "CommonPrefixes")
                {
                    yield break;
                }

            }
        }


    }








}
